<?php

/**
 * 数据统一验证类
 * @author Yorgo Sun (sunshaoxuan@cdeledu.com)
 * @package base
 */

class Validate
{
	public static $DEFAULT = 1;
	public static $NOTNULL = 2;

	function __construct()
	{

	}

	/**
	 *	验证数据
	 *	@param string $method 数据传递的方法
	 *	@param mixed $varname 待验证变量
	 *	@param int $checkmethod 验证级别
	 *	@param mixed $defaultvalue 变量的默认值（若变量为赋值，则变量等于此默认值）
	 *	@return mixed $result 验证后的数据（经过滤的$varname或默认值）
	 */
	public function filterVar($method, $varname, $checkmethod = 1, $defaultvalue = "")
	{
		$method = strtoupper($method);
		if ($checkmethod == self :: $NOTNULL)
			$defaultvalue = "";

		switch ($method)
		{
			case "GET" :
				$result = isset ($_GET[$varname]) ? $this->filterSpecialChars($_GET[$varname], $method) : $defaultvalue;
				break;
			case "POST" :
				$result = isset ($_POST[$varname]) ? $this->filterSpecialChars($_POST[$varname], $method) : $defaultvalue;
				break;
			case "COOKIE" :
				$result = isset ($_COOKIE[$varname]) ? $this->filterSpecialChars($_COOKIE[$varname], $method) : $defaultvalue;
				break;
			case "FILES" :
				$result = isset ($_FILES[$varname]) ? $_FILES[$varname] : $defaultvalue;
				if (!$this->isNull($result))
				{
					if (!is_uploaded_file($_FILES[$varname]["tmp_name"]))
						throw new Exception("upload file error, isn't upload file", '21027001');
					$result["name"] = $this->filterSpecialChars($result["name"], $method);
					$result["type"] = $this->filterSpecialChars($result["type"], $method);
					$result["size"] = $this->filterSpecialChars($result["size"], $method);
					$result["tmp_name"] = $this->filterSpecialChars($result["tmp_name"], $method);
					$result["error"] = $this->filterSpecialChars($result["error"], $method);
				}
				break;
			case "SERVER" :
				$result = isset ($_SERVER[$varname]) ? $this->filterSpecialChars($_SERVER[$varname], $method) : $defaultvalue;
				break;
			default :
				throw new Exception("Error:unknown method", '21027002');
		}

		switch ($checkmethod)
		{
			case self :: $NOTNULL :
				if ($this->isNull($result))
					throw new Exception("Error:".$varname." is null", '21027003');
				break;
			case self :: $DEFAULT :
				if ($this->isNull($result))
					$result = $defaultvalue;
				break;
			default :
				throw new Exception("Error:unknown checkmethod", '21027004');
		}
		return $result;
	}

	/**
	 *	检查变量值是否为空或空字符
	 *	@param mixed $value 被检查的变量
	 *	@return boolen 如果变量为空或为空字符，返回TRUE,否则返回false
	 */
	private function isNull($value)
	{
		if (is_null($value) || $value == "")
		{
			return true;
		}
		else
			return false;
	}

	/**
	 * 字符串参数过滤：对单个或数组进行替换过滤
	 * 1、替换字符串中的'和\
	 * 2、检测js注入
	 * 3、检测sql注入
	 * 
	 * @param string $string	被替换、过滤的字符串
	 * @param string $method	参数传递的方法
	 * 
	 * @return string 替换后的字符串，或抛出异常
	 */
	public function filterSpecialChars($string, $method)
	{
		if (!is_array($string))
		{
			return Validate :: filterSpecialChar($string, $method);
		}
		else
		{
			foreach ($string as $key => $value)
			{
				$ret[$key] = Validate :: filterSpecialChars($value, $method);
			}
			return $ret;
		}
	}

	/**
	 * 字符串参数过滤：仅针对单个字符串进行替换、过滤
	 * 1、替换字符串中的'和\
	 * 2、检测js注入
	 * 3、检测sql注入
	 * 
	 * @param string $string	被替换、过滤的字符串
	 * @param string $method	参数传递的方法
	 * 
	 * @return string 替换后的字符串，或抛出异常
	 */
	public static function filterSpecialChar($string, $method = 'GET')
	{
		$string = get_magic_quotes_gpc() == 1 ? $string : addslashes($string);

		$addon_filter = "^\\+\/v(8|9)|";
		//		$filter = "\b(alert|confirm|prompt)\b|(<|%3C|%253C)\\s*(script|iframe|object)\\b|onerror|expression|onmouseover|onload|GARANT.+?ON|INSERT.+?INTO|(CREATE|DROP).+?TABLE|DELETE.+?FROM|UNION|SELECT|floor|ExtractValue|UpdateXml|UPDATE.+?SET|(ALTER|CREATE|DROP|TRUNCATE)\\s+(DATABASE|USER)";

		$filter = "(<|%3C|%253C)\\s*(script|iframe|object)\\b";
		$filter .= "|\b(alert|confirm|prompt|expression)\\s*\(|(onerror|onmouseover|onload)\\s*=";
		$filter .= "|GARANT.+?ON|INSERT.+?INTO|(CREATE|DROP).+?TABLE|(SELECT|DELETE).+?FROM|\bORD|IFNULL|\b(SELECT|UNION|ExtractValue|UpdateXml|SLEEP)\b|UPDATE.+?SET|(ALTER|CREATE|DROP|TRUNCATE)\\s+(DATABASE|USER)";
		if (strcasecmp($method, 'COOKIE') !== 0)
		{
			$filter = $addon_filter.$filter;
		}

		if (preg_match("/".$filter."/is", $string) == 1)
		{
			echo "<script type='text/javascript'>alert('参数非法');</script>";
			throw new Exception('参数非法', 21027005);
		}

		return $string;
	}

	/**
	 * 过滤多参数分隔（主要用于sql中in的字段，且为整数）
	 */
	public function filterImplode($string, $seg = ",")
	{
		$rows = explode($seg, $string);
		foreach ($rows as $k => $row)
		{
			$rows[$k] = intval($row);
		}

		return implode($seg, $rows);
	}

}
?>